/* eslint-disable no-unused-vars */
/*
 * @Author: wuhao930406 1148547900@qq.com
 * @Date: 2023-10-26 14:06:00
 * @LastEditors: wuhao930406 1148547900@qq.com
 * @LastEditTime: 2023-10-27 17:27:07
 * @FilePath: /eggauthmoblie/app/service/wx.js
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
 */

const Service = require('egg').Service;
const SHA1 = require('crypto-js/sha1');

class WxService extends Service {
  objKeySort(arys) {
    // 先用Object内置类的keys方法获取要排序对象的属性名数组，再利用Array的sort方法进行排序
    const newkey = Object.keys(arys).sort();
    let newObj = ''; // 创建一个新的对象，用于存放排好序的键值对
    for (let i = 0; i < newkey.length; i++) {
      // 遍历newkey数组
      newObj += [ newkey[i] ] + '=' + arys[newkey[i]] + '&';
    }
    return newObj.substring(0, newObj.length - 1);
  }

  async checkSign() {
    const { ctx, app } = this;
    const token = app.config.wechat_config.token; // 替换为你的微信公众号的Token
    const { signature, timestamp, nonce, echostr } = ctx.query;
    const shasum = SHA1([ token, timestamp, nonce ].sort().join('')).toString();
    if (shasum === signature) {
      return echostr;
    }
    return 'Invalid signature';
  }

  // 判断token值从哪里获取
  async fetchAccessToken(code) {
    const { app } = this;
    const access_token = await app.redis.get('access_token');
    console.log(access_token, 'access_token');

    // redis 存在access_token
    if (!access_token) {
      const token = await this.fetchToken(code);
      return token;
    }
    // redis不存在access_token
    const istoken = await this.istoken(access_token);
    if (istoken) {
      return access_token;
    }
    const token = await this.fetchToken(code);
    return token;
  }

  // 判断token是否失效
  async istoken(token) {
    const { ctx, app } = this;
    const openid = await app.redis.get('openid');
    const res = await ctx.curl(
      `https://api.weixin.qq.com/sns/auth?access_token=${token}&openid=${openid}`,
      {
        // 必须指定 method
        method: 'GET',
        dataType: 'json',
      }
    );
    console.log(res, 'istoken');
    return res?.data?.errcode === 0;
  }

  // 获取token 定时任务
  async fetchToken(code) {
    const { ctx, app } = this;
    const appid = app.config.wechat_config.appid;
    const appsecret = app.config.wechat_config.appsecret;
    const refresh_token = await app.redis.get('refresh_token');
    const URL = code
      ? `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appid}&secret=${appsecret}&code=${code}&grant_type=authorization_code`
      : `https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=${appid}&grant_type=refresh_token&refresh_token=${refresh_token}`;
    const res = await ctx.curl(URL, {
      method: 'GET',
      dataType: 'json',
    });
    console.log(res, 'token_response');
    if (res.data.refresh_token) {
      await app.redis.set('refresh_token', res.data.refresh_token);
    }
    if (res.data.openid) {
      await app.redis.set('openid', res.data.openid);
    }
    if (res.data.access_token) {
      await app.redis.set('access_token', res.data.access_token);
      await this.createMenu(res.data.access_token);
      return res.data.access_token;
    }

    return null;
  }

  // 判断ticket值从哪里获取
  async getAccessTicket() {
    const { app } = this;
    const ticket = await app.redis.get('ticket');
    // redis 存在ticket
    console.log(ticket, 'ticket');

    if (!ticket) {
      const res = await this.getTicket();
      return res;
    }
    // redis 存在ticket
    return ticket;
  }

  // 获取ticket 定时任务
  async getTicket() {
    const { ctx, app } = this;
    const access_token = await this.fetchAccessToken();
    console.log(access_token, '换key');
    const res = await ctx.curl(
      `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`,
      {
        // 必须指定 method
        method: 'GET',
        dataType: 'json',
      }
    );
    console.log(res, 'ticket_response');
    if (res.data.ticket) {
      await app.redis.set('ticket', res.data.ticket);
      return res.data.ticket;
    }
    return null;
  }

  async getJsSdkSign(url) {
    const { ctx } = this;
    const appId = ctx.app.config.wechat_config.appid;
    const timestamp = parseInt(new Date().getTime() / 1000);
    const nonceStr = Math.random().toString(36).substring(2, 15);
    const ticket = await this.getAccessTicket();
    const sortStr = this.objKeySort({
      nonceStr,
      jsapi_ticket: ticket,
      timestamp,
      url,
    });
    const signature = SHA1(sortStr).toString();
    const data = {
      appId,
      timestamp,
      nonceStr,
      signature,
      url,
    };

    return data;
  }

  // 创建菜单
  async createMenu(token) {
    const { ctx, app } = this;
    const res = await ctx.curl(
      `https://api.weixin.qq.com/cgi-bin/menu/create?access_token=${token}`,
      {
        method: 'POST',
        contentType: 'json',
        data: {
          button: [
            {
              type: 'click',
              name: '优天辰',
              url: 'http://www.youtianchen.cn/',
            },
            {
              name: '菜单',
              sub_button: [
                {
                  type: 'view',
                  name: '搜索',
                  url: 'http://www.soso.com/',
                },
                {
                  type: 'miniprogram',
                  name: 'wxa',
                  url: 'http://mp.weixin.qq.com',
                  appid: 'wx286b93c14bbf93aa',
                  pagepath: 'pages/lunar/index',
                },
                {
                  type: 'click',
                  name: '赞一下我们',
                  key: 'V1001_GOOD',
                }],
            }],
        },
        dataType: 'json',
      }
    );
    return res?.data;
  }
}

module.exports = WxService;
